#include "audiooutputer.h"
#include <iostream>
#include <QtGlobal>
#include <QTimer>
#include <irrKlang/irrKlang.h>
#include "errormanager.h"
#include "string.h"
#include <QList>

using namespace irrklang;
double vol = 0.5;
QList<QTimer*> registry;
int position = 0;
AudioOutputer* AudioOutputer::instance = NULL;
int timeout[5] = {6*60*1000, 5*60*1000, 5*60*1000, 7*60*1000, 3*60*1000};
std::string pathMap[19] = {"wav/dragon_init.wav","wav/red_buff_init.wav","wav/blue_buff_init.wav","wav/baron_init.wav","wav/ward_init.wav","wav/baron_spawn_fifteen.wav",
                           "wav/blue_buff_spawn.wav","wav/red_buff_fifteen.wav","wav/red_buff_spawn.wav","wav/blue_buff_fifteen.wav",
                           "wav/baron_spawn.wav","wav/dragon_spawn_fifteen.wav","wav/dragon_spawn.wav",
                           "wav/ward_fade_fifteen.wav","wav/ward_fade.wav","wav/baron_spawn_thirty.wav","wav/red_buff_thirty.wav","wav/blue_buff_thirty.wav","wav/dragon_spawn_thrity.wav"};


QTimer* timer1_1;
QTimer* timer1_2;
QTimer* timer1_3;
QTimer* timer2_1;
QTimer* timer2_2;
QTimer* timer2_3;
QTimer* timer3_1;
QTimer* timer3_2;
QTimer* timer3_3;
QTimer* timer4_1;
QTimer* timer4_2;
QTimer* timer4_3;
QTimer* timer5_1;
QTimer* timer5_2;
int semaphora = 0;


irrklang::ISoundEngine* engine;

AudioOutputer::AudioOutputer() : QObject()
{
    if(!engine){
        engine = irrklang::createIrrKlangDevice();
        engine->setSoundVolume(vol);
    }else{
        engine->drop();
        engine = irrklang::createIrrKlangDevice();
        engine->setSoundVolume(vol);
    }

    timer1_1 = new QTimer(this);
    timer1_2 = new QTimer(this);
    timer1_3 = new QTimer(this);
    timer2_1 = new QTimer(this);
    timer2_2 = new QTimer(this);
    timer2_3 = new QTimer(this);
    timer3_1 = new QTimer(this);
    timer3_2 = new QTimer(this);
    timer3_3 = new QTimer(this);
    timer4_1 = new QTimer(this);
    timer4_2 = new QTimer(this);
    timer4_3 = new QTimer(this);
}

AudioOutputer* AudioOutputer::GetInstance()
{
    if(instance==NULL || engine == NULL){
        instance = new AudioOutputer();
    }

    return instance;
}

void AudioOutputer::SetVolume(double volume){
    if(engine){
        engine->setSoundVolume(volume/100);
        vol = volume;
    }
}

void AudioOutputer::Terminate(){
    StopTimer();
    engine->drop();
}

void AudioOutputer::StopTimer(){
    if(timer1_1)
        timer1_1->stop();
    if(timer1_2)
        timer1_2->stop();
    if(timer1_3)
        timer1_3->stop();
    if(timer2_1)
        timer2_1->stop();
    if(timer2_2)
        timer2_2->stop();
    if(timer2_3)
        timer2_3->stop();
    if(timer3_1)
        timer3_1->stop();
    if(timer3_2)
        timer3_2->stop();
    if(timer3_3)
        timer3_3->stop();
    if(timer4_1)
        timer4_1->stop();
    if(timer4_2)
        timer4_2->stop();
    if(timer4_3)
        timer4_3->stop();
    if(timer5_1)
        timer5_1->stop();
    if(timer5_2)
        timer5_2->stop();

    foreach(QTimer* timer , registry)
    {
        timer->stop();
    }

    registry.clear();
    position = 0;


}

void AudioOutputer::OutputSound(int soundId){

    if(!engine){
            QString error = "The sound engine could not be started.";
            ErrorManager::GetInstance()->DisplayError(error);
            return;
    }

    engine->play2D(pathMap[soundId-1].c_str(), false);

    switch(soundId){
           case 1 :
                timer1_1 = new QTimer(this);
                timer1_2 = new QTimer(this);
                timer1_3 = new QTimer(this);
                timer1_1->start(timeout[soundId-1] - 30000);
                timer1_2->start(timeout[soundId-1] - 15000);
                timer1_3->start(timeout[soundId-1]);
                timer1_1->setSingleShot(true);
                timer1_2->setSingleShot(true);
                timer1_3->setSingleShot(true);
                this->connect(timer1_1, SIGNAL(timeout()), SLOT(PlayDragonThirty()));
                this->connect(timer1_2, SIGNAL(timeout()), SLOT(PlayDragonFifteen()));
                this->connect(timer1_3, SIGNAL(timeout()), SLOT(PlayDragon()));
           break;
           case 2 :
                timer2_1 = new QTimer(this);
                timer2_2 = new QTimer(this);
                timer2_3 = new QTimer(this);
                timer2_1->start(timeout[soundId-1] - 30000);
                timer2_2->start(timeout[soundId-1] - 15000);
                timer2_3->start(timeout[soundId-1]);
                timer2_1->setSingleShot(true);
                timer2_2->setSingleShot(true);
                timer2_3->setSingleShot(true);
                this->connect(timer2_1, SIGNAL(timeout()), SLOT(PlayRedThirty()));
                this->connect(timer2_2, SIGNAL(timeout()), SLOT(PlayRedFifteen()));
                this->connect(timer2_3, SIGNAL(timeout()), SLOT(PlayRed()));
           break;
           case 3 :
                timer3_1 = new QTimer(this);
                timer3_2 = new QTimer(this);
                timer3_3 = new QTimer(this);
                timer3_1->start(timeout[soundId-1] - 30000);
                timer3_2->start(timeout[soundId-1] - 15000);
                timer3_3->start(timeout[soundId-1]);
                timer3_1->setSingleShot(true);
                timer3_2->setSingleShot(true);
                timer3_3->setSingleShot(true);
                this->connect(timer3_1, SIGNAL(timeout()), SLOT(PlayBlueThirty()));
                this->connect(timer3_2, SIGNAL(timeout()), SLOT(PlayBlueFifteen()));
                this->connect(timer3_3, SIGNAL(timeout()), SLOT(PlayBlue()));
           break;
           case 4 :
                timer4_1 = new QTimer(this);
                timer4_2 = new QTimer(this);
                timer4_3 = new QTimer(this);
                timer4_1->start(timeout[soundId-1] - 30000);
                timer4_2->start(timeout[soundId-1] - 15000);
                timer4_3->start(timeout[soundId-1]);
                timer4_1->setSingleShot(true);
                timer4_2->setSingleShot(true);
                timer4_3->setSingleShot(true);
                this->connect(timer4_1, SIGNAL(timeout()), SLOT(PlayBaronThirty()));
                this->connect(timer4_2, SIGNAL(timeout()), SLOT(PlayBaronFifteen()));
                this->connect(timer4_3, SIGNAL(timeout()), SLOT(PlayBaron()));
           break;
           case 5 :
                timer5_1 = new QTimer(this);
                timer5_2 = new QTimer(this);
                position++;
                registry.insert(position,timer5_1);
                position++;
                registry.insert(position,timer5_2);
                timer5_1->start(timeout[soundId-1] - 15000);
                timer5_2->start(timeout[soundId-1]);
                timer5_1->setSingleShot(true);
                timer5_2->setSingleShot(true);
                this->connect(timer5_1, SIGNAL(timeout()), SLOT(PlayWardFifteen()));
                this->connect(timer5_2, SIGNAL(timeout()), SLOT(PlayWard()));
            break;

       }
}

void AudioOutputer::PlayDragon(){
    engine->play2D(pathMap[12].c_str(), false);
    timer1_3->stop();
}

void AudioOutputer::PlayDragonFifteen(){
    engine->play2D(pathMap[11].c_str(), false);
    timer1_2->stop();
}
void AudioOutputer::PlayBaron(){
    engine->play2D(pathMap[10].c_str(), false);
    timer4_3->stop();
}
void AudioOutputer::PlayBaronFifteen(){
    engine->play2D(pathMap[5].c_str(), false);
    timer4_2->stop();
}
void AudioOutputer::PlayBlue(){
    engine->play2D(pathMap[6].c_str(), false);
    timer3_3->stop();
}
void AudioOutputer::PlayBlueFifteen(){
    engine->play2D(pathMap[9].c_str(), false);
    timer3_2->stop();
}
void AudioOutputer::PlayRed(){
    engine->play2D(pathMap[8].c_str(), false);
    timer2_3->stop();
}
void AudioOutputer::PlayRedFifteen(){
    engine->play2D(pathMap[7].c_str(), false);
    timer2_2->stop();
}
void AudioOutputer::PlayWard(){
    engine->play2D(pathMap[14].c_str(), false);
    timer5_2->stop();
}
void AudioOutputer::PlayWardFifteen(){
    engine->play2D(pathMap[13].c_str(), false);
    timer5_1->stop();
}
void AudioOutputer::PlayBaronThirty(){
    engine->play2D(pathMap[15].c_str(), false);
    timer4_1->stop();
}
void AudioOutputer::PlayRedThirty(){
    engine->play2D(pathMap[16].c_str(), false);
    timer2_1->stop();
}
void AudioOutputer::PlayBlueThirty(){
    engine->play2D(pathMap[17].c_str(), false);
    timer3_1->stop();
}
void AudioOutputer::PlayDragonThirty(){
    engine->play2D(pathMap[18].c_str(), false);
    timer1_1->stop();
}



